<template>
  <a-tree class="tree" :tree-data="treeData" :expanded-keys="expandedKeys" :auto-expand-parent="autoExpandParent"
    @select="handleNodeClick" @expand="onExpand" block-node show-icon>
    <template #icon="{ key, selected }">
      <SmileOutlined />
    </template>
    <template #switcherIcon="{ switcherCls }"><DownOutlined :class="switcherCls" /></template>
  </a-tree>
</template>

<script setup>
import { DownOutlined, SmileOutlined } from "@ant-design/icons-vue";
import { onMounted, ref, watch } from "vue";

const props = defineProps({
  html: String
});

onMounted(() => {
  // 初始调用一次
  if (props.html) {
    setTreeDataByHtml(props.html);
  }
});

// 目录树数据
const treeData = ref([]);
// 需要展开的父节点列表
const expandedKeys = ref([]);
// 是否自动展开expandedKeys中的父节点
const autoExpandParent = ref(true);

watch(() => props.html, () => {
  // 清空旧数据
  treeData.value = [];
  setTreeDataByHtml(props.html);
});

// 展开/收起节点时触发
const onExpand = keys => {
  expandedKeys.value = keys;
  autoExpandParent.value = true;
};

// 解析HTML，生成目录树
const setTreeDataByHtml = (htmlContent) => {
  // 匹配带id属性的h1-h6标签，如 <h2 id="section-2">标题</h2>
  const regex = /<h([1-6])\s+id="([^"]+)"[^>]*>(.*?)<\/h\1>/gi;
  let match;

  // 用于跟踪各级标题的最后一个节点
  const levelStack = [];

  while ((match = regex.exec(htmlContent)) !== null) {
    const level = parseInt(match[1]);
    const id = match[2];
    const title = match[3]; // 直接获取标签内容

    // 创建目录节点
    const node = {
      title: title,
      level: level,
      id: id,
      children: []
    };

    // 确定父节点
    if (level === 1) {
      // h1标签直接添加为根节点
      treeData.value.push(node);
      levelStack[1] = node; // 更新h1的最后一个节点
    } else {
      // 找到当前层级的父节点（上一级的最后一个节点）
      const parentLevel = level - 1;
      const parentNode = levelStack[parentLevel];

      if (parentNode) {
        parentNode.children.push(node);
        levelStack[level] = node; // 更新当前层级的最后一个节点
      } else {
        // 找不到合适的父节点时，直接添加到根节点
        treeData.value.push(node);
        levelStack[level] = node;
      }
    }
  }
};

// 点击节点时平滑滚动到对应标题
const handleNodeClick = (_, { node }) => {
  const targetElement = document.getElementById(node.id);
  if (!targetElement) return;

  targetElement.scrollIntoView({
    behavior: "smooth",
    block: "start"
  });
};
</script>

<style scoped>
.tree {
  width: 100%;
  overflow: auto;
}

/* 滚动条样式 */
::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}

::-webkit-scrollbar-thumb {
  background-color: #ffffff;
  background-image: -webkit-linear-gradient(45deg,
      rgba(255, 255, 255, 0.4) 25%,
      transparent 25%,
      transparent 50%,
      rgba(255, 255, 255, 0.4) 50%,
      rgba(255, 255, 255, 0.4) 75%,
      transparent 75%,
      transparent);
  border-radius: 32px;
}

::-webkit-scrollbar-track {
  background-color: #ffffff;
  border-radius: 32px;
}
</style>